package com.fly.video.downloader.util.network;


import com.fly.video.downloader.core.os.AsyncTaskResult;
import com.fly.video.downloader.util.Helpers;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.*;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

import javax.net.ssl.*;

/**
 * Created by Administrator on 2018/5/4.
 */

public class DownloaderTask implements Runnable {

    private Downloader downloader;
    public static final int DOWNLOAD_CHUNK_SIZE = 2048; //Same as Okio Segment.SIZE
    public DownloaderTask(Downloader downloader)
    {
        this.downloader = downloader;
    }
    private HashMap<HttpUrl,List<Cookie>> cookieStore = new LinkedHashMap();
    @Override
    public void run() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(10, TimeUnit.SECONDS);
        builder.readTimeout(60, TimeUnit.SECONDS);
        builder.writeTimeout(60, TimeUnit.SECONDS);
        builder.retryOnConnectionFailure(false);
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[] { new MyTrustManager() },new SecureRandom());
            builder.sslSocketFactory(sc.getSocketFactory(),new MyTrustManager() );
            builder.hostnameVerifier(new MyHostnameVerifier());
            builder.cookieJar(new CookieJar() {
                @Override
                public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
                    cookieStore.put(httpUrl, list);
                }

                @Override
                public List<Cookie> loadForRequest(HttpUrl httpUrl) {
                    List<Cookie> cookies = cookieStore.get(httpUrl);
                    return cookies != null ? cookies : new ArrayList<Cookie>();
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

        OkHttpClient client =builder.build();

        File tmpFile = null;
        try {
            tmpFile = downloader.getFile().createTempFile();
            Request request = new Request.Builder()
                    .url(downloader.getUrl())
                    .removeHeader("User-Agent")
                    .addHeader("User-Agent",  Helpers.getPhoneUa())
                    .build();
            File finalTmpFile = tmpFile;
            File finalTmpFile1 = tmpFile;
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    e.printStackTrace();
                    System.out.println("错误");
                    if (finalTmpFile1 != null) finalTmpFile1.delete();
                    downloader.onDownloadProgress(0l,0l);
                    downloader.onDownloadError(new AsyncTaskResult<>(e).getError());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    ResponseBody body = response.body();
                    long contentLength =  body.contentLength();
                    long totalRead = 0;
                    long read;
                    BufferedSource source = body.source();
                    BufferedSink sink = Okio.buffer(Okio.sink(finalTmpFile));
                    while ((read = source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
                        totalRead += read;
                        downloader.onDownloadProgress(totalRead, contentLength);
                    }
                    sink.writeAll(source);
                    sink.flush();
                    sink.close();
                    body.close();
                    response.close();
                    finalTmpFile.renameTo(downloader.getFile());
                    downloader.onDownloadProgress(contentLength, contentLength);
                }
            });

        } catch (Exception e) {
            if (tmpFile != null) tmpFile.delete();
            downloader.onDownloadProgress(0l,0l);
            downloader.onDownloadError(new AsyncTaskResult<>(e).getError());
        }
        downloader.onDownloaded();
    }

}
